<!DOCTYPE html>
<html>

  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
	<meta http-equiv="Cache-Control" content="no-siteapp" />

    <title>xmake v2.5.2 发布, 支持自动拉取交叉工具链和依赖包集成</title>
    <meta name="description" content="xmake 是一个基于 Lua 的轻量级跨平台构建工具，使用 xmake.lua 维护项目构建，相比 makefile/CMakeLists.txt，配置语法更加简洁直观，对新手非常友好，短时间内就能快速入门，能够让用户把更多的精力集中在实际的项目开发上。在 2.5.2 版本中，我们增加了一个重量级的新特性：自动...">

    
    <meta name="keywords" content="xmake,lua,C/C++,toolchains,xrepo,packages,cross-toolchains,tboox" /> 

    <!-- qq oauth -->
    <meta property="qc:admins" content="5211601217706727767255" />

    <!--icon -->
    <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
    <link rel="icon" sizes="192x192" href="/static/img/nice-highres.png" />
	<link rel="apple-touch-icon-precomposed" href="/static/img/apple-touch-icon-57x57-precomposed.png" />
	<link rel="apple-touch-icon-precomposed" sizes="72x72" href="/static/img/apple-touch-icon-72x72-precomposed.png" />
	<link rel="apple-touch-icon-precomposed" sizes="114x114" href="/static/img/apple-touch-icon-114x114-precomposed.png" />
	<link rel="apple-touch-icon-precomposed" sizes="144x144" href="/static/img/apple-touch-icon-144x144-precomposed.png" />
	<link rel="apple-touch-icon-precomposed" sizes="180x180" href="/static/img/retinahd_icon.png" />
	<meta name="msapplication-TileImage" content="/static/img/retinahd_icon.png" />
	
    <link rel="stylesheet" href=" /css/fontawesome/css/font-awesome.min.css ">
    <link rel="stylesheet" href=" /css/main.css ">
    <link rel="canonical" href="https://tboox.org/cn/2021/02/27/xmake-update-v2.5.2/">
    <link rel="alternate" type="application/rss+xml" title="TBOOX Open Source Project" href="https://tboox.org/feed.xml ">
    <link rel="alternate" hreflang="en" href="https://tboox.org/" />
    <link rel="alternate" hreflang="zh-Hans" href="https://tboox.org/cn/" />

    <!-- css -->
    <link href="/css/reward.css" rel="stylesheet" type="text/css"> 




    <script type="text/javascript">
    function isPC(){    
        var userAgentInfo = navigator.userAgent;  
        var Agents = new Array("Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod");    
        var flag = true;    
        for (var v = 0; v < Agents.length; v++) {    
            if (userAgentInfo.indexOf(Agents[v]) > 0) { flag = false; break; }    
        }    
        return flag;    
    }
    </script>

<!-- baidu ads -->



    <!-- baidu ads -->

</head>


  <body>

    <header id="top">
    <div class="wrapper">
        <a href="/cn" class="brand">TBOOX</a>
        <button id="headerMenu" class="menu"><i class="fa fa-bars"></i></button>
        <nav id="headerNav">
            <ul>
                <li>
                    
                    <a href="/?lang=0">
                    
                        <i class="fa fa-home"></i>English
                    </a>
                </li>

                
                    
                    
                    <li>
                        
                            
                            <a href="/cn/project/">
                            
                        
                            <i class="fa fa-bookmark"></i>项目
                        </a>
                    </li>
                    
                    
                
                    
                    
                    
                
                    
                    
                    <li>
                        
                            
                            <a href="/cn/archive/">
                            
                        
                            <i class="fa fa-archive"></i>归档
                        </a>
                    </li>
                    
                    
                
                    
                    
                    
                
                    
                    
                    <li>
                        
                            
                            <a href="/cn/category/">
                            
                        
                            <i class="fa fa-th-list"></i>分类
                        </a>
                    </li>
                    
                    
                
                    
                    
                    
                
                    
                    
                    <li>
                        
                            
                            <a href="/cn/tag/">
                            
                        
                            <i class="fa fa-tags"></i>标记
                        </a>
                    </li>
                    
                    
                
                    
                    
                    
                
                    
                
                    
                    
                    <li>
                        
                            
                            <a href="/cn/docs/">
                            
                        
                            <i class="fa fa-book"></i>文档
                        </a>
                    </li>
                    
                    
                
                    
                    
                    
                
                    
                    
                    <li>
                        
                            
                            <a href="https://xmake.io/#/zh-cn/about/contact" target="_blank" >
                            
                        
                            <i class="fa fa-forumbee"></i>社区
                        </a>
                    </li>
                    
                    
                
                    
                    
                    
                
                    
                    
                    <li>
                        
                            
                            <a href="/cn/donation/">
                            
                        
                            <i class="fa fa-heart"></i>捐助
                        </a>
                    </li>
                    
                    
                
                    
                    
                    
                
                    
                    
                    <li>
                        
                            
                            <a href="/cn/about/">
                            
                        
                            <i class="fa fa-user"></i>关于
                        </a>
                    </li>
                    
                    
                
                    
                    
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                    
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
            </ul>
        </nav>
    </div>
</header>



        <div class="page clearfix" post>
    <div class="left">
        <h1>xmake v2.5.2 发布, 支持自动拉取交叉工具链和依赖包集成</h1>
        <div class="label">

            <div class="label-card">
                <i class="fa fa-calendar"></i>2021-02-27
            </div>

            <div class="label-card">
                
            </div>

            <div class="label-card">
                
            </div>

            <div class="label-card">
            


<!-- <span class="point">•</span> -->
<span class="categories">
  <i class="fa fa-th-list"></i>
  
    
        <a href="/category/#xmake" title="Category: xmake" rel="category">xmake</a>
    
  

  <!-- <span class="point">•</span> -->
</span>


            </div>

            <div class="label-card">
            
<!-- <span class="point">•</span> -->
<span class="pageTag">
  <i class="fa fa-tags"></i>
  
    
        <!--a href="/tag/#xmake" title="Tag: xmake" rel="tag">xmake</a-->
        <a href="/cn/tag/#xmake" title="Tag: xmake" rel="tag">xmake</a>&nbsp;
    
        <!--a href="/tag/#lua" title="Tag: lua" rel="tag">lua</a-->
        <a href="/cn/tag/#lua" title="Tag: lua" rel="tag">lua</a>&nbsp;
    
        <!--a href="/tag/#C%2FC%2B%2B" title="Tag: C/C++" rel="tag">C/C++</a-->
        <a href="/cn/tag/#C/C++" title="Tag: C/C++" rel="tag">C/C++</a>&nbsp;
    
        <!--a href="/tag/#toolchains" title="Tag: toolchains" rel="tag">toolchains</a-->
        <a href="/cn/tag/#toolchains" title="Tag: toolchains" rel="tag">toolchains</a>&nbsp;
    
        <!--a href="/tag/#xrepo" title="Tag: xrepo" rel="tag">xrepo</a-->
        <a href="/cn/tag/#xrepo" title="Tag: xrepo" rel="tag">xrepo</a>&nbsp;
    
        <!--a href="/tag/#packages" title="Tag: packages" rel="tag">packages</a-->
        <a href="/cn/tag/#packages" title="Tag: packages" rel="tag">packages</a>&nbsp;
    
        <!--a href="/tag/#cross-toolchains" title="Tag: cross-toolchains" rel="tag">cross-toolchains</a-->
        <a href="/cn/tag/#cross-toolchains" title="Tag: cross-toolchains" rel="tag">cross-toolchains</a>
    
  

</span>

            </div>

        </div>
        <hr>
        <article itemscope itemtype="http://schema.org/BlogPosting">
        <p><a href="https://github.com/xmake-io/xmake">xmake</a> 是一个基于 Lua 的轻量级跨平台构建工具，使用 xmake.lua 维护项目构建，相比 makefile/CMakeLists.txt，配置语法更加简洁直观，对新手非常友好，短时间内就能快速入门，能够让用户把更多的精力集中在实际的项目开发上。</p>

<p>在 2.5.2 版本中，我们增加了一个重量级的新特性：<code class="highlighter-rouge">自动拉取远程交叉编译工具链</code>。</p>

<p>这是用来干什么的呢，做过交叉编译以及有 C/C++ 项目移植经验的同学应该知道，折腾各种交叉编译工具链，移植编译项目是非常麻烦的一件事，需要自己下载对应工具链，并且配置工具链和编译环境很容易出错导致编译失败。</p>

<p>现在，xmake 已经可以支持自动下载项目所需的工具链，然后使用对应工具链直接编译项目，用户不需要关心如何配置工具链，任何情况下只需要执行 <code class="highlighter-rouge">xmake</code> 命令即可完成编译。</p>

<p><img src="/static/img/xmake/muslcc.gif" alt="" /></p>

<p>甚至对于 C/C++ 依赖包的集成，也可以自动切换到对应工具链编译安装集成，一切完全自动化，完全不需要用户操心。</p>

<p>除了交叉编译工具链，我们也可以自动拉取工具链，比如特定版本的 llvm，llvm-mingw, zig 等各种工具链来参与编译 C/C++/Zig 项目的编译。</p>

<p>即使是 cmake 也还不支持工具链的自动拉取，顶多只能配合 vcpkg/conan 等第三方包管理对 C/C++ 依赖包进行集成，另外，即使对于 C/C++依赖包，xmake 也有自己原生内置的包管理工具，完全无任何依赖。</p>

<ul>
  <li><a href="https://github.com/xmake-io/xmake">项目源码</a></li>
  <li><a href="https://xmake.io/#/zh-cn/">官方文档</a></li>
  <li><a href="https://xmake.io/#/zh-cn/about/course">入门课程</a></li>
</ul>

<h2 id="新特性介绍">新特性介绍</h2>

<h3 id="自动拉取远程交叉编译工具链">自动拉取远程交叉编译工具链</h3>

<p>从 2.5.2 版本开始，我们可以拉取指定的工具链来集成编译项目，我们也支持将依赖包切换到对应的远程工具链参与编译后集成进来。</p>

<p>相关例子代码见：<a href="https://github.com/xmake-io/xmake/tree/master/tests/projects/package">Toolchain/Packages Examples</a></p>

<p>相关的 issue <a href="https://github.com/xmake-io/xmake/issues/1217">#1217</a></p>

<p>当前，我们已经在 <a href="https://github.com/xmake-io/xmake-repo">xmake-repo</a> 仓库收录了以下工具链包，可以让 xmake 远程拉取集成：</p>

<ul>
  <li>llvm</li>
  <li>llvm-mingw</li>
  <li>gnu-rm</li>
  <li>muslcc</li>
  <li>zig</li>
</ul>

<p>虽然现在支持的工具链包不多，当但是整体架构已经打通，后期我们只需要收录更多的工具链进来就行，比如：gcc, tinyc, vs-buildtools 等工具链。</p>

<p>由于 xmake 的包支持语义版本，因此如果项目依赖特定版本的 gcc/clang 编译器，就不要用户去折腾安装了，xmake 会自动检测当前系统的 gcc/clang 版本是否满足需求。</p>

<p>如果版本不满足，那么 xmake 就会走远程拉取，自动帮用户安装集成特定版本的 gcc/clang，然后再去编译项目。</p>

<h4 id="拉取指定版本的-llvm-工具链">拉取指定版本的 llvm 工具链</h4>

<p>我们使用 llvm-10 中的 clang 来编译项目。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">add_requires</span><span class="p">(</span><span class="s2">"llvm 10.x"</span><span class="p">,</span> <span class="p">{</span><span class="n">alias</span> <span class="o">=</span> <span class="s2">"llvm-10"</span><span class="p">})</span>
<span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"binary"</span><span class="p">)</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/*.c)
    set_toolchains("</span><span class="n">llvm</span><span class="err">@</span><span class="n">llvm</span><span class="o">-</span><span class="mi">10</span><span class="s2">")
</span></code></pre>
</div>

<p>其中，<code class="highlighter-rouge">llvm@llvm-10</code> 的前半部分为工具链名，也就是 <code class="highlighter-rouge">toolchain("llvm")</code>，后面的名字是需要被关联工具链包名，也就是 <code class="highlighter-rouge">package("llvm")</code>，不过如果设置了别名，那么会优先使用别名：<code class="highlighter-rouge">llvm-10</code></p>

<p>另外，我们后续还会增加 gcc 工具链包到 xmake-repo，使得用户可以自由切换 gcc-10, gcc-11 等特定版本的 gcc 编译器，而无需用户去手动安装。</p>

<h3 id="拉取交叉编译工具链">拉取交叉编译工具链</h3>

<p>我们也可以拉取指定的交叉编译工具链来编译项目。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">add_requires</span><span class="p">(</span><span class="s2">"muslcc"</span><span class="p">)</span>
<span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"binary"</span><span class="p">)</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/*.c)
    set_toolchains("</span><span class="err">@</span><span class="n">muslcc</span><span class="s2">")
</span></code></pre>
</div>

<p>muslcc 是 https://musl.cc 提供的一款交叉编译工具链，默认 xmake 会自动集成编译 <code class="highlighter-rouge">x86_64-linux-musl-</code> 目标平台。</p>

<p>当然，我们也可以通过 <code class="highlighter-rouge">xmake f -a arm64</code> 切换到 <code class="highlighter-rouge">aarch64-linux-musl-</code> 目标平台来进行交叉编译。</p>

<h4 id="拉取工具链并且集成对应工具链编译的依赖包">拉取工具链并且集成对应工具链编译的依赖包</h4>

<p>我们也可以使用指定的muslcc交叉编译工具链去编译和集成所有的依赖包。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">add_requires</span><span class="p">(</span><span class="s2">"muslcc"</span><span class="p">)</span>
<span class="n">add_requires</span><span class="p">(</span><span class="s2">"zlib"</span><span class="p">,</span> <span class="s2">"libogg"</span><span class="p">,</span> <span class="p">{</span><span class="n">system</span> <span class="o">=</span> <span class="kc">false</span><span class="p">})</span>

<span class="n">set_toolchains</span><span class="p">(</span><span class="s2">"@muslcc"</span><span class="p">)</span>

<span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"binary"</span><span class="p">)</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/*.c"</span><span class="p">)</span>
    <span class="n">add_packages</span><span class="p">(</span><span class="s2">"zlib"</span><span class="p">,</span> <span class="s2">"libogg"</span><span class="p">)</span>
</code></pre>
</div>

<p>这个时候，工程里面配置的 zlib, libogg 等依赖包，也会切换使用 muslcc 工具链，自动下载编译然后集成进来。</p>

<p>我们也可以通过 <code class="highlighter-rouge">set_plat/set_arch</code> 固定平台，这样只需要一个 xmake 命令，就可以完成整个交叉编译环境的集成以及架构切换。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">add_requires</span><span class="p">(</span><span class="s2">"muslcc"</span><span class="p">)</span>
<span class="n">add_requires</span><span class="p">(</span><span class="s2">"zlib"</span><span class="p">,</span> <span class="s2">"libogg"</span><span class="p">,</span> <span class="p">{</span><span class="n">system</span> <span class="o">=</span> <span class="kc">false</span><span class="p">})</span>

<span class="n">set_plat</span><span class="p">(</span><span class="s2">"cross"</span><span class="p">)</span>
<span class="n">set_arch</span><span class="p">(</span><span class="s2">"arm64"</span><span class="p">)</span>
<span class="n">set_toolchains</span><span class="p">(</span><span class="s2">"@muslcc"</span><span class="p">)</span>

<span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"binary"</span><span class="p">)</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/*.c"</span><span class="p">)</span>
    <span class="n">add_packages</span><span class="p">(</span><span class="s2">"zlib"</span><span class="p">,</span> <span class="s2">"libogg"</span><span class="p">)</span>
</code></pre>
</div>

<p>完整例子见：<a href="https://github.com/xmake-io/xmake/blob/master/tests/projects/package/toolchain_muslcc/xmake.lua">Examples (muslcc)</a></p>

<h4 id="拉取集成-zig-工具链">拉取集成 Zig 工具链</h4>

<p>xmake 会先下载特定版本的 zig 工具链，然后使用此工具链编译 zig 项目，当然用户如果已经自行安装了 zig 工具链，xmake 也会自动检测对应版本是否满足，如果满足需求，那么会直接使用它，无需重复下载安装。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">add_rules</span><span class="p">(</span><span class="s2">"mode.debug"</span><span class="p">,</span> <span class="s2">"mode.release"</span><span class="p">)</span>
<span class="n">add_requires</span><span class="p">(</span><span class="s2">"zig 0.7.x"</span><span class="p">)</span>

<span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"binary"</span><span class="p">)</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/*.zig"</span><span class="p">)</span>
    <span class="n">set_toolchains</span><span class="p">(</span><span class="s2">"@zig"</span><span class="p">)</span>
</code></pre>
</div>

<h3 id="增加对-zig-cc-编译器支持">增加对 zig cc 编译器支持</h3>

<p><code class="highlighter-rouge">zig cc</code> 是 zig 内置的 c/c++ 编译器，可以完全独立进行 c/c++ 代码的编译和链接，完全不依赖 gcc/clang/msvc，非常给力。</p>

<p>因此，我们完全可以使用它来编译 c/c++ 项目，关键是 zig 的工具链还非常轻量，仅仅几十M 。</p>

<p>我们只需要切换到 zig 工具链即可完成编译：</p>

<div class="language-bash highlighter-rouge"><pre class="highlight"><code><span class="gp">$ </span>xmake f --toolchain<span class="o">=</span>zig
<span class="gp">$ </span>xmake
<span class="o">[</span> 25%]: compiling.release src/main.c
<span class="s2">"zig cc"</span> -c -arch x86_64 -fvisibility<span class="o">=</span>hidden -O3 -DNDEBUG -o build/.objs/xmake_test/macosx/x86_64/release/src/main.c.o src/main.c
<span class="o">[</span> 50%]: linking.release <span class="nb">test</span>
<span class="s2">"zig c++"</span> -o build/macosx/x86_64/release/test build/.objs/xmake_test/macosx/x86_64/release/src/main.c.o -arch x86_64 -stdlib<span class="o">=</span>libc++ -Wl,-x -lz
<span class="o">[</span>100%]: build ok!
</code></pre>
</div>

<p>另外，<code class="highlighter-rouge">zig cc</code> 的另外一个强大之处在于，它还支持不同架构的交叉编译，太 happy 了。</p>

<p>通过 xmake，我们也只需再额外切换下架构到 arm64，即可实现对 arm64 的交叉编译，例如：</p>

<div class="language-bash highlighter-rouge"><pre class="highlight"><code><span class="gp">$ </span>xmake f -a arm64 --toolchain<span class="o">=</span>zig
<span class="gp">$ </span>xmake
<span class="o">[</span> 25%]: compiling.release src/main.c
<span class="s2">"zig cc"</span> -c -target aarch64-macos-gnu -arch arm64 -fvisibility<span class="o">=</span>hidden -O3 -DNDEBUG -o build/.objs/xmake_test/macosx/arm64/release/src/main.c.o src/main.c
checking <span class="k">for </span>flags <span class="o">(</span>-MMD -MF<span class="o">)</span> ... ok
checking <span class="k">for </span>flags <span class="o">(</span>-fdiagnostics-color<span class="o">=</span>always<span class="o">)</span> ... ok
<span class="o">[</span> 50%]: linking.release xmake_test
<span class="s2">"zig c++"</span> -o build/macosx/arm64/release/xmake_test build/.objs/xmake_test/macosx/arm64/release/src/main.c.o -target aarch64-macos-gnu -arch arm64 -stdlib<span class="o">=</span>libc++ -Wl,-x -lz
<span class="o">[</span>100%]: build ok!
</code></pre>
</div>

<p>即使你是在在 macOS，也可以用 <code class="highlighter-rouge">zig cc</code> 去交叉编译 windows/x64 目标程序，相当于替代了 mingw 干的事情。</p>

<div class="language-bash highlighter-rouge"><pre class="highlight"><code><span class="gp">$ </span>xmake f -p windows -a x64 --toolchain<span class="o">=</span>zig
<span class="gp">$ </span>xmake
</code></pre>
</div>

<h3 id="自动导出所有-windowsdll-中的符号">自动导出所有 windows/dll 中的符号</h3>

<p>cmake 中有这样一个功能：<code class="highlighter-rouge">WINDOWS_EXPORT_ALL_SYMBOLS</code>，安装 cmake 文档中的说法：</p>

<p><a href="https://cmake.org/cmake/help/latest/prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS.html">https://cmake.org/cmake/help/latest/prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS.html</a></p>

<blockquote>
  <p>Enable this boolean property to automatically create a module definition (.def) file with all global symbols found
in the input .obj files for a SHARED library (or executable with ENABLE_EXPORTS) on Windows.
The module definition file will be passed to the linker causing all symbols to be exported from the .dll. For global data symbols,
__declspec(dllimport) must still be used when compiling against the code in the .dll. All other function symbols will be automatically exported and imported by callers.
This simplifies porting projects to Windows by reducing the need for explicit dllexport markup, even in C++ classes.</p>
</blockquote>

<p>大体意思就是：</p>

<blockquote>
  <p>启用此布尔属性，可以自动创建一个模块定义(.def)文件，其中包含在Windows上的共享库(或使用ENABLE_EXPORTS的可执行文件)的输入.obj文件中找到的所有全局符号。
模块定义文件将被传递给链接器，使所有符号从.dll中导出。对于全局数据符号，当对.dll中的代码进行编译时，仍然必须使用__declspec(dllimport)。
所有其它的函数符号将被调用者自动导出和导入。这就简化了将项目移植到 Windows 的过程，减少了对显式 dllexport 标记的需求，甚至在 C++ 类中也是如此。</p>
</blockquote>

<p>现在，xmake 中也提供了类似的特性，可以快速全量导出 windows/dll 中的符号，来简化对第三方项目移植过程中，对符号导出的处理。另外，如果项目中的符号太多，也可以用此来简化代码中的显式导出需求。</p>

<p>我们只需在对应生成的 dll 目标上，配置 <code class="highlighter-rouge">utils.symbols.export_all</code> 规则即可。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"foo"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"shared"</span><span class="p">)</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/foo.c"</span><span class="p">)</span>
    <span class="n">add_rules</span><span class="p">(</span><span class="s2">"utils.symbols.export_all"</span><span class="p">)</span>

<span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"binary"</span><span class="p">)</span>
    <span class="n">add_deps</span><span class="p">(</span><span class="s2">"foo"</span><span class="p">)</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/main.c"</span><span class="p">)</span>
</code></pre>
</div>

<p>xmake 会自动扫描所有的 obj 对象文件，然后生成 def 符号导出文件，传入 link.exe 实现快速全量导出。</p>

<h3 id="转换-mingwdlla-到-msvclib">转换 mingw/.dll.a 到 msvc/.lib</h3>

<p>这个特性也是参考自 CMAKE_GNUtoMS 功能，可以把MinGW生成的动态库（xxx.dll &amp; xxx.dll.a）转换成Visual Studio可以识别的格式（xxx.dll &amp; xxx.lib），从而实现混合编译。</p>

<p>这个功能对Fortran &amp; C++混合项目特别有帮助，因为VS不提供fortran编译器，只能用MinGW的gfortran来编译fortran部分，然后和VS的项目链接。
往往这样的项目同时有一些其他的库以vs格式提供，因此纯用MinGW编译也不行，只能使用cmake的这个功能来混合编译。</p>

<p>因此，xmake 也提供了一个辅助模块接口去支持它，使用方式如下：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">import</span><span class="p">(</span><span class="s2">"utils.platform.gnu2mslib"</span><span class="p">)</span>

<span class="n">gnu2mslib</span><span class="p">(</span><span class="s2">"xxx.lib"</span><span class="p">,</span> <span class="s2">"xxx.dll.a"</span><span class="p">)</span>
<span class="n">gnu2mslib</span><span class="p">(</span><span class="s2">"xxx.lib"</span><span class="p">,</span> <span class="s2">"xxx.def"</span><span class="p">)</span>
<span class="n">gnu2mslib</span><span class="p">(</span><span class="s2">"xxx.lib"</span><span class="p">,</span> <span class="s2">"xxx.dll.a"</span><span class="p">,</span> <span class="p">{</span><span class="n">dllname</span> <span class="o">=</span> <span class="s2">"xxx.dll"</span><span class="p">,</span> <span class="n">arch</span> <span class="o">=</span> <span class="s2">"x64"</span><span class="p">})</span>
</code></pre>
</div>

<p>支持从 def 生成 xxx.lib ，也支持从 xxx.dll.a 自动导出 .def ，然后再生成 xxx.lib</p>

<p>具体细节见：<a href="https://github.com/xmake-io/xmake/issues/1181">issue #1181</a></p>

<h3 id="实现批处理命令来简化自定义规则">实现批处理命令来简化自定义规则</h3>

<p>为了简化用户自定义 rule 的配置，xmake 新提供了 <code class="highlighter-rouge">on_buildcmd_file</code>, <code class="highlighter-rouge">on_buildcmd_files</code> 等自定义脚本入口，
我们可以通过 batchcmds 对象，构造一个批处理命令行任务，xmake 在实际执行构建的时候，一次性执行这些命令。</p>

<p>这对于 <code class="highlighter-rouge">xmake project</code> 此类工程生成器插件非常有用，因为生成器生成的第三方工程文件并不支持 <code class="highlighter-rouge">on_build_files</code> 此类内置脚本的执行支持。</p>

<p>但是 <code class="highlighter-rouge">on_buildcmd_file</code> 构造的最终结果，就是一批原始的 cmd 命令行，可以直接给其他工程文件作为 custom commands 来执行。</p>

<p>另外，相比 <code class="highlighter-rouge">on_build_file</code>，它也简化对扩展文件的编译实现，更加的可读易配置，对用户也更加友好。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">rule</span><span class="p">(</span><span class="s2">"foo"</span><span class="p">)</span>
    <span class="n">set_extensions</span><span class="p">(</span><span class="s2">".xxx"</span><span class="p">)</span>
    <span class="n">on_buildcmd_file</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">,</span> <span class="n">batchcmds</span><span class="p">,</span> <span class="n">sourcefile</span><span class="p">,</span> <span class="n">opt</span><span class="p">)</span>
        <span class="n">batchcmds</span><span class="p">:</span><span class="n">vrunv</span><span class="p">(</span><span class="s2">"gcc"</span><span class="p">,</span> <span class="p">{</span><span class="s2">"-o"</span><span class="p">,</span> <span class="n">objectfile</span><span class="p">,</span> <span class="s2">"-c"</span><span class="p">,</span> <span class="n">sourcefile</span><span class="p">})</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<p>除了 <code class="highlighter-rouge">batchcmds:vrunv</code>，我们还支持一些其他的批处理命令，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">batchcmds</span><span class="p">:</span><span class="n">show</span><span class="p">(</span><span class="s2">"hello %s"</span><span class="p">,</span> <span class="s2">"xmake"</span><span class="p">)</span>
<span class="n">batchcmds</span><span class="p">:</span><span class="n">vrunv</span><span class="p">(</span><span class="s2">"gcc"</span><span class="p">,</span> <span class="p">{</span><span class="s2">"-o"</span><span class="p">,</span> <span class="n">objectfile</span><span class="p">,</span> <span class="s2">"-c"</span><span class="p">,</span> <span class="n">sourcefile</span><span class="p">},</span> <span class="p">{</span><span class="n">envs</span> <span class="o">=</span> <span class="p">{</span><span class="n">LD_LIBRARY_PATH</span><span class="o">=</span><span class="s2">"/xxx"</span><span class="p">}})</span>
<span class="n">batchcmds</span><span class="p">:</span><span class="n">mkdir</span><span class="p">(</span><span class="s2">"/xxx"</span><span class="p">)</span> <span class="c1">-- and cp, mv, rm, ln ..</span>
<span class="n">batchcmds</span><span class="p">:</span><span class="n">compile</span><span class="p">(</span><span class="n">sourcefile_cx</span><span class="p">,</span> <span class="n">objectfile</span><span class="p">,</span> <span class="p">{</span><span class="n">configs</span> <span class="o">=</span> <span class="p">{</span><span class="n">includedirs</span> <span class="o">=</span> <span class="n">sourcefile_dir</span><span class="p">,</span> <span class="n">languages</span> <span class="o">=</span> <span class="p">(</span><span class="n">sourcekind</span> <span class="o">==</span> <span class="s2">"cxx"</span> <span class="ow">and</span> <span class="s2">"c++11"</span><span class="p">)}})</span>
<span class="n">batchcmds</span><span class="p">:</span><span class="n">link</span><span class="p">(</span><span class="n">objectfiles</span><span class="p">,</span> <span class="n">targetfile</span><span class="p">,</span> <span class="p">{</span><span class="n">configs</span> <span class="o">=</span> <span class="p">{</span><span class="n">linkdirs</span> <span class="o">=</span> <span class="s2">""</span><span class="p">}})</span>
</code></pre>
</div>

<p>同时，我们在里面也简化对依赖执行的配置，下面是一个完整例子：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">rule</span><span class="p">(</span><span class="s2">"lex"</span><span class="p">)</span>
    <span class="n">set_extensions</span><span class="p">(</span><span class="s2">".l"</span><span class="p">,</span> <span class="s2">".ll"</span><span class="p">)</span>
    <span class="n">on_buildcmd_file</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">,</span> <span class="n">batchcmds</span><span class="p">,</span> <span class="n">sourcefile_lex</span><span class="p">,</span> <span class="n">opt</span><span class="p">)</span>

        <span class="c1">-- imports</span>
        <span class="n">import</span><span class="p">(</span><span class="s2">"lib.detect.find_tool"</span><span class="p">)</span>

        <span class="c1">-- get lex</span>
        <span class="kd">local</span> <span class="n">lex</span> <span class="o">=</span> <span class="nb">assert</span><span class="p">(</span><span class="n">find_tool</span><span class="p">(</span><span class="s2">"flex"</span><span class="p">)</span> <span class="ow">or</span> <span class="n">find_tool</span><span class="p">(</span><span class="s2">"lex"</span><span class="p">),</span> <span class="s2">"lex not found!"</span><span class="p">)</span>

        <span class="c1">-- get c/c++ source file for lex</span>
        <span class="kd">local</span> <span class="n">extension</span> <span class="o">=</span> <span class="n">path</span><span class="p">.</span><span class="n">extension</span><span class="p">(</span><span class="n">sourcefile_lex</span><span class="p">)</span>
        <span class="kd">local</span> <span class="n">sourcefile_cx</span> <span class="o">=</span> <span class="n">path</span><span class="p">.</span><span class="n">join</span><span class="p">(</span><span class="n">target</span><span class="p">:</span><span class="n">autogendir</span><span class="p">(),</span> <span class="s2">"rules"</span><span class="p">,</span> <span class="s2">"lex_yacc"</span><span class="p">,</span> <span class="n">path</span><span class="p">.</span><span class="n">basename</span><span class="p">(</span><span class="n">sourcefile_lex</span><span class="p">)</span> <span class="o">..</span> <span class="p">(</span><span class="n">extension</span> <span class="o">==</span> <span class="s2">".ll"</span> <span class="ow">and</span> <span class="s2">".cpp"</span> <span class="ow">or</span> <span class="s2">".c"</span><span class="p">))</span>

        <span class="c1">-- add objectfile</span>
        <span class="kd">local</span> <span class="n">objectfile</span> <span class="o">=</span> <span class="n">target</span><span class="p">:</span><span class="n">objectfile</span><span class="p">(</span><span class="n">sourcefile_cx</span><span class="p">)</span>
        <span class="nb">table.insert</span><span class="p">(</span><span class="n">target</span><span class="p">:</span><span class="n">objectfiles</span><span class="p">(),</span> <span class="n">objectfile</span><span class="p">)</span>

        <span class="c1">-- add commands</span>
        <span class="n">batchcmds</span><span class="p">:</span><span class="n">show_progress</span><span class="p">(</span><span class="n">opt</span><span class="p">.</span><span class="n">progress</span><span class="p">,</span> <span class="s2">"${color.build.object}compiling.lex %s"</span><span class="p">,</span> <span class="n">sourcefile_lex</span><span class="p">)</span>
        <span class="n">batchcmds</span><span class="p">:</span><span class="n">mkdir</span><span class="p">(</span><span class="n">path</span><span class="p">.</span><span class="n">directory</span><span class="p">(</span><span class="n">sourcefile_cx</span><span class="p">))</span>
        <span class="n">batchcmds</span><span class="p">:</span><span class="n">vrunv</span><span class="p">(</span><span class="n">lex</span><span class="p">.</span><span class="n">program</span><span class="p">,</span> <span class="p">{</span><span class="s2">"-o"</span><span class="p">,</span> <span class="n">sourcefile_cx</span><span class="p">,</span> <span class="n">sourcefile_lex</span><span class="p">})</span>
        <span class="n">batchcmds</span><span class="p">:</span><span class="n">compile</span><span class="p">(</span><span class="n">sourcefile_cx</span><span class="p">,</span> <span class="n">objectfile</span><span class="p">)</span>

        <span class="c1">-- add deps</span>
        <span class="n">batchcmds</span><span class="p">:</span><span class="n">add_depfiles</span><span class="p">(</span><span class="n">sourcefile_lex</span><span class="p">)</span>
        <span class="n">batchcmds</span><span class="p">:</span><span class="n">set_depmtime</span><span class="p">(</span><span class="n">os</span><span class="p">.</span><span class="n">mtime</span><span class="p">(</span><span class="n">objectfile</span><span class="p">))</span>
        <span class="n">batchcmds</span><span class="p">:</span><span class="n">set_depcache</span><span class="p">(</span><span class="n">target</span><span class="p">:</span><span class="n">dependfile</span><span class="p">(</span><span class="n">objectfile</span><span class="p">))</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<p>我们从上面的配置可以看到，整体执行命令列表非常清晰，而如果我们用 <code class="highlighter-rouge">on_build_file</code> 来实现，可以对比下之前这个规则的配置，就能直观感受到新接口的配置方式确实简化了不少：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">rule</span><span class="p">(</span><span class="s2">"lex"</span><span class="p">)</span>

    <span class="c1">-- set extension</span>
    <span class="n">set_extensions</span><span class="p">(</span><span class="s2">".l"</span><span class="p">,</span> <span class="s2">".ll"</span><span class="p">)</span>

    <span class="c1">-- load lex/flex</span>
    <span class="n">before_load</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span>
        <span class="n">import</span><span class="p">(</span><span class="s2">"core.project.config"</span><span class="p">)</span>
        <span class="n">import</span><span class="p">(</span><span class="s2">"lib.detect.find_tool"</span><span class="p">)</span>
        <span class="kd">local</span> <span class="n">lex</span> <span class="o">=</span> <span class="n">config</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"__lex"</span><span class="p">)</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="n">lex</span> <span class="k">then</span>
            <span class="n">lex</span> <span class="o">=</span> <span class="n">find_tool</span><span class="p">(</span><span class="s2">"flex"</span><span class="p">)</span> <span class="ow">or</span> <span class="n">find_tool</span><span class="p">(</span><span class="s2">"lex"</span><span class="p">)</span>
            <span class="k">if</span> <span class="n">lex</span> <span class="ow">and</span> <span class="n">lex</span><span class="p">.</span><span class="n">program</span> <span class="k">then</span>
                <span class="n">config</span><span class="p">.</span><span class="n">set</span><span class="p">(</span><span class="s2">"__lex"</span><span class="p">,</span> <span class="n">lex</span><span class="p">.</span><span class="n">program</span><span class="p">)</span>
                <span class="n">cprint</span><span class="p">(</span><span class="s2">"checking for Lex ... ${color.success}%s"</span><span class="p">,</span> <span class="n">lex</span><span class="p">.</span><span class="n">program</span><span class="p">)</span>
            <span class="k">else</span>
                <span class="n">cprint</span><span class="p">(</span><span class="s2">"checking for Lex ... ${color.nothing}${text.nothing}"</span><span class="p">)</span>
                <span class="n">raise</span><span class="p">(</span><span class="s2">"lex/flex not found!"</span><span class="p">)</span>
            <span class="k">end</span>
        <span class="k">end</span>
    <span class="k">end</span><span class="p">)</span>

    <span class="c1">-- build lex file</span>
    <span class="n">on_build_file</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">,</span> <span class="n">sourcefile_lex</span><span class="p">,</span> <span class="n">opt</span><span class="p">)</span>

        <span class="c1">-- imports</span>
        <span class="n">import</span><span class="p">(</span><span class="s2">"core.base.option"</span><span class="p">)</span>
        <span class="n">import</span><span class="p">(</span><span class="s2">"core.theme.theme"</span><span class="p">)</span>
        <span class="n">import</span><span class="p">(</span><span class="s2">"core.project.config"</span><span class="p">)</span>
        <span class="n">import</span><span class="p">(</span><span class="s2">"core.project.depend"</span><span class="p">)</span>
        <span class="n">import</span><span class="p">(</span><span class="s2">"core.tool.compiler"</span><span class="p">)</span>
        <span class="n">import</span><span class="p">(</span><span class="s2">"private.utils.progress"</span><span class="p">)</span>

        <span class="c1">-- get lex</span>
        <span class="kd">local</span> <span class="n">lex</span> <span class="o">=</span> <span class="nb">assert</span><span class="p">(</span><span class="n">config</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"__lex"</span><span class="p">),</span> <span class="s2">"lex not found!"</span><span class="p">)</span>

        <span class="c1">-- get extension: .l/.ll</span>
        <span class="kd">local</span> <span class="n">extension</span> <span class="o">=</span> <span class="n">path</span><span class="p">.</span><span class="n">extension</span><span class="p">(</span><span class="n">sourcefile_lex</span><span class="p">)</span>

        <span class="c1">-- get c/c++ source file for lex</span>
        <span class="kd">local</span> <span class="n">sourcefile_cx</span> <span class="o">=</span> <span class="n">path</span><span class="p">.</span><span class="n">join</span><span class="p">(</span><span class="n">target</span><span class="p">:</span><span class="n">autogendir</span><span class="p">(),</span> <span class="s2">"rules"</span><span class="p">,</span> <span class="s2">"lex_yacc"</span><span class="p">,</span> <span class="n">path</span><span class="p">.</span><span class="n">basename</span><span class="p">(</span><span class="n">sourcefile_lex</span><span class="p">)</span> <span class="o">..</span> <span class="p">(</span><span class="n">extension</span> <span class="o">==</span> <span class="s2">".ll"</span> <span class="ow">and</span> <span class="s2">".cpp"</span> <span class="ow">or</span> <span class="s2">".c"</span><span class="p">))</span>
        <span class="kd">local</span> <span class="n">sourcefile_dir</span> <span class="o">=</span> <span class="n">path</span><span class="p">.</span><span class="n">directory</span><span class="p">(</span><span class="n">sourcefile_cx</span><span class="p">)</span>

        <span class="c1">-- get object file</span>
        <span class="kd">local</span> <span class="n">objectfile</span> <span class="o">=</span> <span class="n">target</span><span class="p">:</span><span class="n">objectfile</span><span class="p">(</span><span class="n">sourcefile_cx</span><span class="p">)</span>

        <span class="c1">-- load compiler</span>
        <span class="kd">local</span> <span class="n">compinst</span> <span class="o">=</span> <span class="n">compiler</span><span class="p">.</span><span class="n">load</span><span class="p">((</span><span class="n">extension</span> <span class="o">==</span> <span class="s2">".ll"</span> <span class="ow">and</span> <span class="s2">"cxx"</span> <span class="ow">or</span> <span class="s2">"cc"</span><span class="p">),</span> <span class="p">{</span><span class="n">target</span> <span class="o">=</span> <span class="n">target</span><span class="p">})</span>

        <span class="c1">-- get compile flags</span>
        <span class="kd">local</span> <span class="n">compflags</span> <span class="o">=</span> <span class="n">compinst</span><span class="p">:</span><span class="n">compflags</span><span class="p">({</span><span class="n">target</span> <span class="o">=</span> <span class="n">target</span><span class="p">,</span> <span class="n">sourcefile</span> <span class="o">=</span> <span class="n">sourcefile_cx</span><span class="p">})</span>

        <span class="c1">-- add objectfile</span>
        <span class="nb">table.insert</span><span class="p">(</span><span class="n">target</span><span class="p">:</span><span class="n">objectfiles</span><span class="p">(),</span> <span class="n">objectfile</span><span class="p">)</span>

        <span class="c1">-- load dependent info</span>
        <span class="kd">local</span> <span class="n">dependfile</span> <span class="o">=</span> <span class="n">target</span><span class="p">:</span><span class="n">dependfile</span><span class="p">(</span><span class="n">objectfile</span><span class="p">)</span>
        <span class="kd">local</span> <span class="n">dependinfo</span> <span class="o">=</span> <span class="n">option</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"rebuild"</span><span class="p">)</span> <span class="ow">and</span> <span class="p">{}</span> <span class="ow">or</span> <span class="p">(</span><span class="n">depend</span><span class="p">.</span><span class="n">load</span><span class="p">(</span><span class="n">dependfile</span><span class="p">)</span> <span class="ow">or</span> <span class="p">{})</span>

        <span class="c1">-- need build this object?</span>
        <span class="kd">local</span> <span class="n">depvalues</span> <span class="o">=</span> <span class="p">{</span><span class="n">compinst</span><span class="p">:</span><span class="n">program</span><span class="p">(),</span> <span class="n">compflags</span><span class="p">}</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="n">depend</span><span class="p">.</span><span class="n">is_changed</span><span class="p">(</span><span class="n">dependinfo</span><span class="p">,</span> <span class="p">{</span><span class="n">lastmtime</span> <span class="o">=</span> <span class="n">os</span><span class="p">.</span><span class="n">mtime</span><span class="p">(</span><span class="n">objectfile</span><span class="p">),</span> <span class="n">values</span> <span class="o">=</span> <span class="n">depvalues</span><span class="p">})</span> <span class="k">then</span>
            <span class="k">return</span>
        <span class="k">end</span>

        <span class="c1">-- trace progress info</span>
        <span class="n">progress</span><span class="p">.</span><span class="n">show</span><span class="p">(</span><span class="n">opt</span><span class="p">.</span><span class="n">progress</span><span class="p">,</span> <span class="s2">"${color.build.object}compiling.lex %s"</span><span class="p">,</span> <span class="n">sourcefile_lex</span><span class="p">)</span>

        <span class="c1">-- ensure the source file directory</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="p">.</span><span class="n">isdir</span><span class="p">(</span><span class="n">sourcefile_dir</span><span class="p">)</span> <span class="k">then</span>
            <span class="n">os</span><span class="p">.</span><span class="n">mkdir</span><span class="p">(</span><span class="n">sourcefile_dir</span><span class="p">)</span>
        <span class="k">end</span>

        <span class="c1">-- compile lex</span>
        <span class="n">os</span><span class="p">.</span><span class="n">vrunv</span><span class="p">(</span><span class="n">lex</span><span class="p">,</span> <span class="p">{</span><span class="s2">"-o"</span><span class="p">,</span> <span class="n">sourcefile_cx</span><span class="p">,</span> <span class="n">sourcefile_lex</span><span class="p">})</span>

        <span class="c1">-- trace</span>
        <span class="k">if</span> <span class="n">option</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"verbose"</span><span class="p">)</span> <span class="k">then</span>
            <span class="nb">print</span><span class="p">(</span><span class="n">compinst</span><span class="p">:</span><span class="n">compcmd</span><span class="p">(</span><span class="n">sourcefile_cx</span><span class="p">,</span> <span class="n">objectfile</span><span class="p">,</span> <span class="p">{</span><span class="n">compflags</span> <span class="o">=</span> <span class="n">compflags</span><span class="p">}))</span>
        <span class="k">end</span>

        <span class="c1">-- compile c/c++ source file for lex</span>
        <span class="n">dependinfo</span><span class="p">.</span><span class="n">files</span> <span class="o">=</span> <span class="p">{}</span>
        <span class="nb">assert</span><span class="p">(</span><span class="n">compinst</span><span class="p">:</span><span class="n">compile</span><span class="p">(</span><span class="n">sourcefile_cx</span><span class="p">,</span> <span class="n">objectfile</span><span class="p">,</span> <span class="p">{</span><span class="n">dependinfo</span> <span class="o">=</span> <span class="n">dependinfo</span><span class="p">,</span> <span class="n">compflags</span> <span class="o">=</span> <span class="n">compflags</span><span class="p">}))</span>

        <span class="c1">-- update files and values to the dependent file</span>
        <span class="n">dependinfo</span><span class="p">.</span><span class="n">values</span> <span class="o">=</span> <span class="n">depvalues</span>
        <span class="nb">table.insert</span><span class="p">(</span><span class="n">dependinfo</span><span class="p">.</span><span class="n">files</span><span class="p">,</span> <span class="n">sourcefile_lex</span><span class="p">)</span>
        <span class="n">depend</span><span class="p">.</span><span class="n">save</span><span class="p">(</span><span class="n">dependinfo</span><span class="p">,</span> <span class="n">dependfile</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<p>关于这个的详细说明和背景，见：<a href="https://github.com/xmake-io/xmake/issues/1246">issue 1246</a></p>

<h3 id="依赖包配置改进">依赖包配置改进</h3>

<h4 id="使用-add_extsources-改进包名查找">使用 add_extsources 改进包名查找</h4>

<p>关于远程依赖包定义这块，我们也新增了 <code class="highlighter-rouge">add_extsources</code> 和 <code class="highlighter-rouge">on_fetch</code> 两个配置接口，可以更好的配置 xmake 在安装 C/C++ 包的过程中，对系统库的查找过程。</p>

<p>至于具体背景，我们可以举个例子，比如我们在 <a href="https://github.com/xmake-io/xmake-repo">xmake-repo</a> 仓库新增了一个 <code class="highlighter-rouge">package("libusb")</code> 的包。</p>

<p>那么用户就可以通过下面的方式，直接集成使用它：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">add_requires</span><span class="p">(</span><span class="s2">"libusb"</span><span class="p">)</span>
<span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"binary"</span><span class="p">)</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/*.c"</span><span class="p">)</span>
    <span class="n">add_packages</span><span class="p">(</span><span class="s2">"libusb"</span><span class="p">)</span>
</code></pre>
</div>

<p>如果用户系统上确实没有安装 libusb，那么 xmake 会自动下载 libusb 库源码，自动编译安装集成，没啥问题。</p>

<p>但如果用户通过 <code class="highlighter-rouge">apt install libusb-1.0</code> 安装了 libusb 库到系统，那么按理 xmake 应该会自动优先查找用户安装到系统环境的 libusb 包，直接使用，避免额外的下载编译安装。</p>

<p>但是问题来了，xmake 内部通过 <code class="highlighter-rouge">find_package("libusb")</code> 并没有找打它，这是为什么呢？因为通过 apt 安装的 libusb 包名是 <code class="highlighter-rouge">libusb-1.0</code>, 而不是 libusb。</p>

<p>我们只能通过 <code class="highlighter-rouge">pkg-config --cflags libusb-1.0</code> 才能找到它，但是 xmake 内部的默认 find_package 逻辑并不知道 <code class="highlighter-rouge">libusb-1.0</code> 的存在，所以找不到。</p>

<p>因此为了更好地适配不同系统环境下，系统库的查找，我们可以通过 <code class="highlighter-rouge">add_extsources("pkgconfig::libusb-1.0")</code> 去让 xmake 改进查找逻辑，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">package</span><span class="p">(</span><span class="s2">"libusb"</span><span class="p">)</span>
    <span class="n">add_extsources</span><span class="p">(</span><span class="s2">"pkgconfig::libusb-1.0"</span><span class="p">)</span>
    <span class="n">on_install</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">package</span><span class="p">)</span>
        <span class="c1">-- ...</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<p>另外，我们也可以通过这个方式，改进查找 homebrew/pacman 等其他包管理器安装的包，例如：<code class="highlighter-rouge">add_extsources("pacman::libusb-1.0")</code>。</p>

<h4 id="使用-on_fetch-完全定制系统库查找">使用 on_fetch 完全定制系统库查找</h4>

<p>如果不同系统下安装的系统库，仅仅只是包名不同，那么使用 <code class="highlighter-rouge">add_extsources</code> 改进系统库查找已经足够，简单方便。</p>

<p>但是如果有些安装到系统的包，位置更加复杂，想要找到它们，也许需要一些额外的脚本才能实现，例如：windows 下注册表的访问去查找包等等，这个时候，我们就可以通过 <code class="highlighter-rouge">on_fetch</code> 完全定制化查找系统库逻辑。</p>

<p>还是以 libusb 为例，我们不用 <code class="highlighter-rouge">add_extsources</code>，可以使用下面的方式，实现相同的效果，当然，我们可以在里面做更多的事情。</p>

<div class="highlighter-rouge"><pre class="highlight"><code>package("libusb")
    on_fetch("linux", function(package, opt)
        if opt.system then
            return find_package("pkgconfig::libusb-1.0")
        end
    end)
</code></pre>
</div>

<h3 id="manifest-文件支持">manifest 文件支持</h3>

<p>在新版本中，我们还新增了对 windows <code class="highlighter-rouge">.manifest</code> 文件的支持，只需要通过 <code class="highlighter-rouge">add_files</code> 添加进来即可。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">add_rules</span><span class="p">(</span><span class="s2">"mode.debug"</span><span class="p">,</span> <span class="s2">"mode.release"</span><span class="p">)</span>
<span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"binary"</span><span class="p">)</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/*.cpp"</span><span class="p">)</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/*.manifest"</span><span class="p">)</span>
</code></pre>
</div>

<h3 id="xrepo-命令改进">xrepo 命令改进</h3>

<p>关于 xrepo 命令，我们也稍微改进了下，现在可以通过下面的命令，批量卸载删除已经安装的包，支持模式匹配：</p>

<div class="language-bash highlighter-rouge"><pre class="highlight"><code><span class="gp">$ </span>xrepo remove --all
<span class="gp">$ </span>xrepo remove --all zlib pcr<span class="k">*</span>
</code></pre>
</div>

<h3 id="包的依赖导出支持">包的依赖导出支持</h3>

<p>我们也改进了 <code class="highlighter-rouge">add_packages</code>，使其也支持 <code class="highlighter-rouge"><span class="p">{</span><span class="err">public</span><span class="w"> </span><span class="err">=</span><span class="w"> </span><span class="err">true</span><span class="p">}</span></code> 来导出包配置给父 target。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">add_rules</span><span class="p">(</span><span class="s2">"mode.debug"</span><span class="p">,</span> <span class="s2">"mode.release"</span><span class="p">)</span>
<span class="n">add_requires</span><span class="p">(</span><span class="s2">"pcre2"</span><span class="p">)</span>

<span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"shared"</span><span class="p">)</span>
    <span class="n">add_packages</span><span class="p">(</span><span class="s2">"pcre2"</span><span class="p">,</span> <span class="p">{</span><span class="n">public</span> <span class="o">=</span> <span class="kc">true</span><span class="p">})</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/test.cpp"</span><span class="p">)</span>

<span class="n">target</span><span class="p">(</span><span class="s2">"demo"</span><span class="p">)</span>
    <span class="n">add_deps</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"binary"</span><span class="p">)</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/main.cpp"</span><span class="p">)</span>  <span class="c1">-- 我们可以在这里使用被 test 目标导出 pcre2 库</span>
</code></pre>
</div>

<p>至于具体导出哪些配置呢？</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 默认私有，但是 links/linkdirs 还是会自动导出</span>
<span class="n">add_packages</span><span class="p">(</span><span class="s2">"pcre2"</span><span class="p">)</span>

<span class="c1">-- 全部导出。包括 includedirs, defines</span>
<span class="n">add_packages</span><span class="p">(</span><span class="s2">"pcre2"</span><span class="p">,</span> <span class="p">{</span><span class="n">public</span> <span class="o">=</span> <span class="kc">true</span><span class="p">})</span>
</code></pre>
</div>

<h2 id="更新内容">更新内容</h2>

<h3 id="新特性">新特性</h3>

<ul>
  <li><a href="https://github.com/xmake-io/xmake/issues/955#issuecomment-766481512">#955</a>: 支持 <code class="highlighter-rouge">zig cc</code> 和 <code class="highlighter-rouge">zig c++</code> 作为 c/c++ 编译器</li>
  <li><a href="https://github.com/xmake-io/xmake/issues/955#issuecomment-768193083">#955</a>: 支持使用 zig 进行交叉编译</li>
  <li><a href="https://github.com/xmake-io/xmake/issues/1177">#1177</a>: 改进终端和 color codes 探测</li>
  <li><a href="https://github.com/xmake-io/xmake/issues/1216">#1216</a>: 传递自定义 includes 脚本给 xrepo</li>
  <li>添加 linuxos 内置模块获取 linux 系统信息</li>
  <li><a href="https://github.com/xmake-io/xmake/issues/1217">#1217</a>: 支持当编译项目时自动拉取工具链</li>
  <li><a href="https://github.com/xmake-io/xmake/issues/1123">#1123</a>: 添加 <code class="highlighter-rouge">rule("utils.symbols.export_all")</code> 自动导出所有 windows/dll 中的符号</li>
  <li><a href="https://github.com/xmake-io/xmake/issues/1181">#1181</a>: 添加 <code class="highlighter-rouge">utils.platform.gnu2mslib(mslib, gnulib)</code> 模块接口去转换 mingw/xxx.dll.a 到 msvc xxx.lib</li>
  <li><a href="https://github.com/xmake-io/xmake/issues/1246">#1246</a>: 改进规则支持新的批处理命令去简化自定义规则实现</li>
  <li><a href="https://github.com/xmake-io/xmake/issues/1239">#1239</a>: 添加 <code class="highlighter-rouge">add_extsources</code> 去改进外部包的查找</li>
  <li><a href="https://github.com/xmake-io/xmake/issues/1241">#1241</a>: 支持为 windows 程序添加 .manifest 文件参与链接</li>
  <li>支持使用 <code class="highlighter-rouge">xrepo remove --all</code> 命令去移除所有的包，并且支持模式匹配</li>
  <li><a href="https://github.com/xmake-io/xmake/issues/1254">#1254</a>: 支持导出包配置给父 target，实现包配置的依赖继承</li>
</ul>

<h3 id="改进">改进</h3>

<ul>
  <li><a href="https://github.com/xmake-io/xmake/issues/1226">#1226</a>: 添加缺失的 Qt 头文件搜索路径</li>
  <li><a href="https://github.com/xmake-io/xmake/issues/1183">#1183</a>: 改进 C++ 语言标准，以便支持 Qt6</li>
  <li><a href="https://github.com/xmake-io/xmake/issues/1237">#1237</a>: 为 vsxmake 插件添加 qt.ui 文件</li>
  <li>改进 vs/vsxmake 插件去支持预编译头文件和智能提示</li>
  <li><a href="https://github.com/xmake-io/xmake/issues/1090">#1090</a>: 简化自定义规则</li>
  <li><a href="https://github.com/xmake-io/xmake/issues/1065">#1065</a>: 改进 protobuf 规则，支持 compile_commands 生成器</li>
  <li><a href="https://github.com/xmake-io/xmake/issues/1249">#1249</a>: 改进 vs/vsxmake 生成器去支持启动工程设置</li>
  <li><a href="https://github.com/xmake-io/xmake/issues/605">#605</a>: 改进 add_deps 和 add_packages 直接的导出 links 顺序</li>
  <li>移除废弃的 <code class="highlighter-rouge">add_defines_h_if_ok</code> and <code class="highlighter-rouge">add_defines_h</code> 接口</li>
</ul>

<h3 id="bugs-修复">Bugs 修复</h3>

<ul>
  <li><a href="https://github.com/xmake-io/xmake/issues/1219">#1219</a>: 修复版本检测和更新</li>
  <li><a href="https://github.com/xmake-io/xmake/issues/1235">#1235</a>: 修复 includes 搜索路径中带有空格编译不过问题</li>
</ul>

        </article>
        <hr>

        <!-- baidu ads -->
        

        <!-- reward -->
        <div style="text-align: center;">
            <button id="rewardButton" disable="enable" onclick="var qr = document.getElementById('QR'); if (qr.style.display === 'none') {qr.style.display='block';} else {qr.style.display='none'}">
              <span>赏</span>
            </button>
            <div id="QR" style="display: none;">
                <div id="wechat" style="display: inline-block">
                  <img id="wechat_qr" src="/static/img/weixin.png" alt="WeChat Pay"/>
                  <p>微信打赏</p>
                </div>
                <div id="alipay" style="display: inline-block">
                  <img id="alipay_qr" src="/static/img/alipay.png" alt="Alipay"/>
                  <p>支付宝打赏</p>
                </div>
            </div>
        </div>

        
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
            
                
                    
                    <h2 id="english">English</h2>
                    <ul>
                    
                    <li class="relatedPost">
                        <a href="/2021/02/27/xmake-update-v2.5.2/">xmake v2.5.2 released, Support pull remote cross-toolchain and package integration
                        
                        </a>
                    </li>
                    
                    
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
        
            
        
            
            
                
            
        
            
        
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
        
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
        
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
        
            
        
            
            
                
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
        
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
        
            </ul>
        

        
        
            
        
            
            
            
                
                    
                        
                        <h2 id="similar_posts">相关文章</h2>
                        <ul>
                        
                        <li class="relatedPost">
                            <a href="/cn/2021/12/17/xmake-update-v2.6.2/">xmake v2.6.2 发布，新增 Linux 内核驱动模块构建支持
                            
                            </a>
                        </li>
                        
                        
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
            
        
            
        
            
            
            
                
                    
                        
                        <li class="relatedPost">
                            <a href="/cn/2021/12/03/xmake-update-v2.6.1/">xmake v2.6.1 发布，使用 Lua5.4 运行时，Rust 和 C++ 混合编译支持
                            
                            </a>
                        </li>
                        
                        
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
            
        
            
        
            
            
            
                
                    
                        
                        <li class="relatedPost">
                            <a href="/cn/2021/10/30/xmake-update-v2.5.9/">xmake v2.5.9 发布，改进 C++20 模块，并支持 Nim, Keil MDK 和 Unity Build
                            
                            </a>
                        </li>
                        
                        
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
            
        
            
        
            
            
            
                
                    
                        
                        <li class="relatedPost">
                            <a href="/cn/2021/10/08/xmake-update-v2.5.8/">xmake v2.5.8 发布，新增 Pascal/Swig 程序和 Lua53 运行时支持
                            
                            </a>
                        </li>
                        
                        
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
            
        
            
        
            
            
            
                
                    
                        
                        <li class="relatedPost">
                            <a href="/cn/2021/08/29/xmake-update-v2.5.7/">xmake v2.5.7 发布，包依赖锁定和 Vala/Metal 语言编译支持
                            
                            </a>
                        </li>
                        
                        
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
            
        
        
            </ul>
        

        <div class="post-recent">
    <div class="pre">

        

        

        
        
        

        

        

        
        
        <p><strong>上一篇</strong> <a href="/cn/2021/01/22/luarocks-build-xmake-v1.0/">一个使用 xmake 构建 c/c++ 模块的 luarocks 插件</a></p>
        
    </div>

    <div class="nex">

        

        

        
        
        

        

        

        
        
        <p><strong>下一篇</strong> <a href="/cn/2021/04/08/xmake-update-v2.5.3/">xmake v2.5.3 发布，支持构建 linux bpf 程序和 Conda 包集成</a></p>
        
    </div>
</div>


        <h2 id="comments">评论</h2>
        






<div id="gitalk-container"></div>
<link rel="stylesheet" href="/css/gitalk.css">
<script src="/js/gitalk.min.js"></script>

<script>
const gitalk = new Gitalk({
  clientID: '73946dc1d9e2276ad0da',
  clientSecret: '12a3cb94361ba3ebc6ecb68cf80d592bfaa8106d',
  repo: 'tboox.github.io',
  owner: 'waruqi',
  admin: ['waruqi'],
  id: location.pathname,       
  language: 'zh-CN',
  distractionFreeMode: false  
})

gitalk.render('gitalk-container')
</script>





    </div>
    <button class="anchor"><i class="fa fa-anchor"></i></button>
    <div class="right">
        <div class="wrap">

            <!-- codefund ads -->
            

            <!-- Content -->
            <div class="side content">
                <div>
                    内容
                </div>
                <ul id="content-side" class="content-ul">
                    <li><a href="#english">English</a></li>
                    <li><a href="#similar_posts">相关文章</a></li>
                    <li><a href="#comments">评论</a></li>
                </ul>
            </div>


            <!-- baidu ads -->
            
            
            <br>
            <div class="side">
                <div>
                    <i class="fa fa-external-link"></i>
                    链接
                </div>
                <ul class="content-ul">
                  <li><a href="http://github.com/waruqi/tbox">tbox</a></li>
                  <li><a href="http://www.xmake.io">xmake</a></li>
                  <li><a href="https://github.com/waruqi">github</a></li>
                </ul>
            </div> 

            <!-- xmake courses -->
            <br>
            <div class="side">
                <div>
                    <i class="fa fa-external-link"></i>
                    xmake 入门课程
                </div>
                <a href="https://xmake.io/#/zh-cn/about/course" target="_blank">
                <img src="/static/img/xmake-course.png" alt="course" width="256" height="193">
                </a>
            </div>

            <!-- qqgroup -->
            <br>
            <div class="side">
                <div>
                    <i class="fa fa-external-link"></i>
                    技术交流群（QQ）
                </div>
                <img src="/static/img/qqgroup.png" alt="qqgroup" width="256" height="284">
            </div> 

            <!-- google ads -->
            

            <!-- baidu ads -->
            

        </div>
    </div>

    <!-- baidu ads -->
    
</div>
<script>
/**
 * target _blank
 */
(function() {
    var aTags = document.querySelectorAll('article a:not([id])')
    for (var i = 0; i < aTags.length; i++) {
        aTags[i].setAttribute('target', '_blank')
    }
}());
</script>
<script src="/js/pageContent.js " charset="utf-8"></script>



    <footer class="site-footer">
    <div class="wrapper">
        <p class="description">
             Copyright (c) 2016-2020 tboox.org 
        </p>
        <p class="contact">
            
            <a href="https://github.com/waruqi" title="GitHub"><i class="fa fa-github" aria-hidden="true"></i></a> 
             
            
            <a href="mailto:waruqi@gmail.com" title="email"><i class="fa fa-envelope-o" aria-hidden="true"></i></a> 
            
            
            <a href="https://twitter.com/waruqi" title="Twitter"><i class="fa fa-twitter" aria-hidden="true"></i></a> 
            
            <a href="/feed.xml" title="feed"><i class="fa fa-feed" aria-hidden="true"></i></a> 
        </p>
        <p class="power">
            <span>
                Site powered by <a href="https://jekyllrb.com/">Jekyll</a> & <a href="https://github.com/Gaohaoyang">HyG</a> & <a href="https://pages.github.com/">Github Pages</a>.
            </span>
        </p>
    </div>
</footer>

    <div class="back-to-top">
    <a href="#top" class="scroll">
        <i class="fa fa-arrow-up" aria-hidden="true"></i>
    </a>
</div>

    <script src=" /js/main.js " charset="utf-8"></script>
    <script src=" /js/scroll.min.js " charset="utf-8"></script>
  </body>

</html>
